<?php


namespace app\api\service;


use app\api\model\User as UserModel;
use think\Exception;

class UserToken extends Token
{
    const PowerUser  = 16;
    const PowerSuper = 32;

    protected $code;
    protected $app_id;
    protected $app_secret;
    protected $url;

    public function __construct ($code)
    {
        // 设置wx相关配置
        $this->code = $code;
        $this->app_id = config('wx.app_id');
        $this->app_secret = config('wx.app_secret');
        $this->url = sprintf(config('wx.url'), $this->app_id, $this->app_secret, $this->code);
    }

    /**
     * 判断用户ID是否为当前登录的用户ID
     * @param $user_id
     * @return bool
     * @throws Exception
     * @throws \app\lib\exception\ThrowError
     */
    public static function checkCurrentUserId($user_id)
    {
        $currentUid = self::getCurrentUid();
        return $currentUid == $user_id ? true : false;
    }

    /**
     * 检查用户权限，用户和管理员都可以访问
     * @return bool
     * @throws Exception
     * @throws \app\lib\exception\ThrowError
     */
    public static function checkExclusiveScope()
    {
        $scope = self::getTokenVal('scope');
        if (!empty($scope) && $scope == UserToken::PowerUser)
        {
            return true;
        }
        else
        {
            T(100003, [], 403);
        }
    }

    /**
     * 检查用户权限，用户和管理员都可以访问
     * @return bool
     * @throws Exception
     * @throws \app\lib\exception\ThrowError
     */
    public static function checkPrimaryScope()
    {
        $scope = self::getTokenVal('scope');
        if (!empty($scope) && $scope >= UserToken::PowerUser)
        {
            return true;
        }
        else
        {
            T(100003, [], 403);
        }
    }

    /**
     * 获取Token
     * @param $code
     * @return bool
     * @throws Exception
     * @throws \app\lib\exception\ThrowError
     */
    public function get()
    {
        // 通过code，获取用户wx信息
        $wxResult = curl_get($this->url);

        if (empty($wxResult))
        {
            throw new Exception('微信那边有问题啦，获取不到token');
        }
        else
        {
            $wxResult = json_decode($wxResult, true);
            $loginFail = isset($wxResult['errcode']);

            if ($loginFail)
            {
                $errorMsg = $wxResult['errmsg'];
                T(100001, ['field' => $errorMsg]);
            }
            else
            {
                // 获取成功，开始颁发Token令牌
                return self::grantToken($wxResult);
            }
        }
    }

    /**
     * 颁发Token令牌
     * @param $wxResult
     */
    private function grantToken($wxResult)
    {
        // 获取open_id
        $openid = $wxResult['openid'];

        // 检查app_id是否已经存在User表中
        $userInfo = UserModel::getUserByOpenId($openid);

        // 不存在，则新增一条用户记录
        if (empty($userInfo))
        {
            $userInfo = UserModel::createUserByOpenId($openid);
            $uid = $userInfo->id;
        }
        else
        {
            $uid = $userInfo->id;
        }

        // 4.生成令牌，存入缓存
        $cacheValue = $wxResult;
        $cacheValue['uid'] = $uid;
        $cacheValue['scope'] = self::PowerUser;
        $token = self::saveToken2Cache($cacheValue);
        // 5.把令牌返回给客户端
        return $token;
    }

    /**
     * 把token设置到缓存里面
     * @param $cacheValue
     * @return string
     * @throws \app\lib\exception\ThrowError
     */
    private function saveToken2Cache($cacheValue)
    {
        // 1.生成随机字符串组成Token
        $token = self::generateToken($cacheValue['uid']);

        // 2.设置缓存
        $expire_time = config('wx.token_expire_time');
        $result = cache($token, json_encode($cacheValue), $expire_time);

        if (!$result)
        {
            // 设置缓存失败
            T(600000);
        }
        return $token;
    }
}